package com.buli.blmall.admin.utils;

import org.yaml.snakeyaml.Yaml;

import java.io.*;
import java.util.Map;
import java.util.Properties;

/**
 * @className: PropertiesUtil
 * @author: Xiang.Gao
 * @date: 2025/11/14
 * @description:
 */

public class PropertiesUtil {

    private static Properties props = new Properties();

    static {
        try {
            loadFromClasspath("application.properties");
            loadYamlFromClasspath("application.yml");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        System.out.println(PropertiesUtil.getProperty("key"));
        System.out.println(PropertiesUtil.getProperty("server.port"));
    }

    /**
     * 加载配置文件
     * @param filePath 配置文件路径
     * @throws IOException 文件读取异常
     */
    public static void load(String filePath) throws IOException {
        try (InputStream inputStream = new FileInputStream(filePath)) {
            props.load(inputStream);
        }
    }

    /**
     * 从classpath加载配置文件
     * @param resourceName 资源名称
     * @throws IOException 文件读取异常
     */
    public static void loadFromClasspath(String resourceName) throws IOException {
        try (InputStream inputStream = PropertiesUtil.class.getClassLoader().getResourceAsStream(resourceName)) {
            if (inputStream == null) {
                throw new FileNotFoundException("配置文件未找到: " + resourceName);
            }
            props.load(inputStream);
        }
    }

    /**
     * 从classpath加载YAML配置文件
     * @param resourceName 资源名称
     * @throws IOException 文件读取异常
     */
    public static void loadYamlFromClasspath(String resourceName) throws IOException {
        try (InputStream inputStream = PropertiesUtil.class.getClassLoader().getResourceAsStream(resourceName)) {
            if (inputStream == null) {
                throw new FileNotFoundException("配置文件未找到: " + resourceName);
            }
            loadYaml(inputStream);
        }
    }


    /**
     * 加载YAML配置
     * @param inputStream 输入流
     */
    private static void loadYaml(InputStream inputStream) {
        Yaml yaml = new Yaml();
        Map<String, Object> yamlData = yaml.load(inputStream);
        convertYamlToProperties(yamlData, "");
    }

    /**
     * 将YAML数据转换为Properties格式
     * @param yamlData YAML数据
     * @param prefix 前缀
     */
    @SuppressWarnings("unchecked")
    private static void convertYamlToProperties(Map<String, Object> yamlData, String prefix) {
        for (Map.Entry<String, Object> entry : yamlData.entrySet()) {
            String key = prefix.isEmpty() ? entry.getKey() : prefix + "." + entry.getKey();
            Object value = entry.getValue();

            if (value instanceof Map) {
                // 递归处理嵌套的Map
                convertYamlToProperties((Map<String, Object>) value, key);
            } else {
                // 将值转换为字符串并存储
                props.setProperty(key, value != null ? value.toString() : "");
            }
        }
    }


    /**
     * 获取字符串类型的配置值
     * @param key 配置键
     * @return 配置值
     */
    public static String getProperty(String key) {
        return props.getProperty(key);
    }

    /**
     * 获取字符串类型的配置值，带默认值
     * @param key 配置键
     * @param defaultValue 默认值
     * @return 配置值或默认值
     */
    public static String getProperty(String key, String defaultValue) {
        return props.getProperty(key, defaultValue);
    }

    /**
     * 获取整数类型的配置值
     * @param key 配置键
     * @return 配置值
     */
    public static int getIntProperty(String key) {
        return Integer.parseInt(props.getProperty(key));
    }

    /**
     * 获取整数类型的配置值，带默认值
     * @param key 配置键
     * @param defaultValue 默认值
     * @return 配置值或默认值
     */
    public static int getIntProperty(String key, int defaultValue) {
        String value = props.getProperty(key);
        return value != null ? Integer.parseInt(value) : defaultValue;
    }

    /**
     * 获取布尔类型的配置值
     * @param key 配置键
     * @return 配置值
     */
    public static boolean getBooleanProperty(String key) {
        return Boolean.parseBoolean(props.getProperty(key));
    }

    /**
     * 获取布尔类型的配置值，带默认值
     * @param key 配置键
     * @param defaultValue 默认值
     * @return 配置值或默认值
     */
    public static boolean getBooleanProperty(String key, boolean defaultValue) {
        String value = props.getProperty(key);
        return value != null ? Boolean.parseBoolean(value) : defaultValue;
    }

    /**
     * 设置配置项
     * @param key 配置键
     * @param value 配置值
     */
    public static void setProperty(String key, String value) {
        props.setProperty(key, value);
    }

    /**
     * 保存配置到文件
     * @param filePath 文件路径
     * @param comments 注释
     * @throws IOException 文件写入异常
     */
    public static void store(String filePath, String comments) throws IOException {
        try (OutputStream outputStream = new FileOutputStream(filePath)) {
            props.store(outputStream, comments);
        }
    }

    /**
     * 检查是否包含指定键
     * @param key 配置键
     * @return 是否包含
     */
    public static boolean containsKey(String key) {
        return props.containsKey(key);
    }

}
